package com.hdw.med.controller;

import com.hdw.common.base.BaseException;
import com.hdw.common.base.BaseResult;
import com.hdw.common.constant.CommonResultConstant;
import com.hdw.common.util.DBUtil;
import com.hdw.common.vo.LayMsg;
import com.hdw.common.vo.PaginationVO;
import com.hdw.med.MedConstant;
import com.hdw.med.api.CommonTableDDLService;
import com.hdw.med.api.MdMedPubfldService;
import com.hdw.med.api.MdMedTbFldService;
import com.hdw.med.api.MdMedTbService;
import com.hdw.med.bean.model.MdMedPubfld;
import com.hdw.med.bean.model.MdMedTb;
import com.hdw.med.bean.model.MdMedTbFld;
import com.hdw.med.bean.vo.AlterTableParamVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * mdMedPubfld控制器
 * Created by hozeData on 2021/07/05.
 */
@RestController
@RequestMapping("/etl/mdMedPubfld/")
@Api(tags = "元数据-公共字段管理")
@CrossOrigin(origins = "*", maxAge = 3600)
public class MdMedPubfldController {
    public static final String DEFAULT_DIM_COLUMN_CD = "cd";
    public static final String DEFAULT_DIM_COLUMN_NA = "na";
    public static final String DEFAULT_DIM_COLUMN_DES = "des";
    public static final String DEFAULT_DIM_COLUMN_EUTP = "eu_tp";

    @Autowired
    MdMedPubfldService mdMedPubfldService;
    @Autowired
    private CommonTableDDLService commonTableDDLService;
    @Autowired
    private MdMedTbService mdMedTbService;
    @Autowired
    private MdMedTbFldService mdMedTbFldService;

    @ApiOperation(value = "分页查询")
    @RequestMapping(value = "findByPage", method = RequestMethod.GET)
    public LayMsg findByPage(String filter, Integer page, Integer limit) {
        PaginationVO<MdMedPubfld> pageVO = mdMedPubfldService.findPageByLike(filter, page, limit);
        return LayMsg.success().addCount(pageVO.getTotal()).addData(pageVO.getEntryList());
    }

    @ApiOperation(value = "根据字段前缀查询")
    @RequestMapping(value = "findByFldPrefix", method = RequestMethod.GET)
    public LayMsg findByFldPrefix(String idPubFld) {
        List<MdMedPubfld> pageVO = mdMedPubfldService.findByFldPrefix(idPubFld);
        return LayMsg.success().addData(pageVO);
    }

    @ApiOperation(value = "条件查询")
    @RequestMapping(value = "findByModel", method = RequestMethod.GET)
    public LayMsg findByModel(String str) {
        List<MdMedPubfld> pageVO = mdMedPubfldService.findByModel(new MdMedPubfld());
        return LayMsg.success().addData(pageVO);
    }


    @ApiOperation(value = "查询所有维度表")
    @RequestMapping(value = "findDimTable", method = RequestMethod.GET)
    public LayMsg findDimTable() {
        List<String> pageVO = mdMedPubfldService.findDimTable();
        return LayMsg.success().addData(pageVO);
    }

    @ApiOperation(value = "查询所有是维度的公共字段且含有维度表")
    @RequestMapping(value = "findIsDimPubfld", method = RequestMethod.GET)
    public LayMsg findIsDimPubfld(Integer page, Integer limit) {
        PaginationVO<MdMedPubfld> pageVO = mdMedPubfldService.findIsDimPubfld(page, limit);
        return LayMsg.success().addCount(pageVO.getTotal()).addData(pageVO.getEntryList());
    }

    @ApiOperation(value = "维度表的字段")
    @RequestMapping(value = "saveDimTableFld", method = RequestMethod.POST)
    public LayMsg saveDimTableFld(@RequestBody List<MdMedTbFld> mdMedTbFlds) {
        Long idTb = null;
        for (MdMedTbFld mdMedTbFld : mdMedTbFlds) {
            idTb = mdMedTbFld.getIdTb();
            if (idTb != null) break;
        }
        if (idTb == null) return LayMsg.fail().addMsg("失败：无默认列");

        MdMedTbFld model = new MdMedTbFld();
        model.setIdTb(idTb);
        List<MdMedTbFld> flds = mdMedTbFldService.findByModel(model);
        if (flds == null || flds.size() == 0) return LayMsg.fail().addMsg(String.format("失败：未找到默认列[%s]", idTb));
        Map<String, MdMedTbFld> mapOld = new HashMap<>();
        for (MdMedTbFld fld : flds) {
            mapOld.put(fld.getIdPubfld(), fld);
        }
        Map<String, MdMedTbFld> mapNew = new HashMap<>();
        for (MdMedTbFld fld : mdMedTbFlds) {
            mapNew.put(fld.getIdPubfld(), fld);
        }
        //处理默认列
        mapNew.put(DEFAULT_DIM_COLUMN_EUTP, mapOld.get(DEFAULT_DIM_COLUMN_EUTP));
        MdMedTbFld oldFld = mapOld.get(DEFAULT_DIM_COLUMN_CD);
        MdMedTbFld newFld = mapNew.get(DEFAULT_DIM_COLUMN_CD);
        if (oldFld == null) return LayMsg.fail().addMsg(String.format("失败：未找到默认列元数据[%s]", DEFAULT_DIM_COLUMN_CD));
        mapNew.put(DEFAULT_DIM_COLUMN_CD, this.getDefaultDimFld(oldFld, newFld));
        oldFld = mapOld.get(DEFAULT_DIM_COLUMN_NA);
        newFld = mapNew.get(DEFAULT_DIM_COLUMN_NA);
        if (oldFld == null) return LayMsg.fail().addMsg(String.format("失败：未找到默认列元数据[%s]", DEFAULT_DIM_COLUMN_NA));
        mapNew.put(DEFAULT_DIM_COLUMN_NA, this.getDefaultDimFld(oldFld, newFld));
        oldFld = mapOld.get(DEFAULT_DIM_COLUMN_DES);
        newFld = mapNew.get(DEFAULT_DIM_COLUMN_DES);
        if (oldFld == null) return LayMsg.fail().addMsg(String.format("失败：未找到默认列元数据[%s]", DEFAULT_DIM_COLUMN_DES));
        mapNew.put(DEFAULT_DIM_COLUMN_DES, this.getDefaultDimFld(oldFld, newFld));


        MdMedTb mdMedTb = mdMedTbService.getById(idTb);
        if (mdMedTb == null) return LayMsg.fail().addMsg(String.format("失败：未找到表元数据[%s]", idTb));
        Boolean isSuccess;
        try {
            isSuccess = commonTableDDLService.alterTableByMedOtherDB(new AlterTableParamVO(mdMedTb, new ArrayList<>(mapNew.values()), null), DBUtil.META_DB);
        } catch (BaseException e) {
            e.printStackTrace();
            return LayMsg.fail().addMsg(e.getMessage());
        }
        if (isSuccess) {
            return LayMsg.success().addCount(mdMedTbFlds.size()).addData(mdMedTbFlds);
        } else {
            return LayMsg.fail().addMsg("失败：修改表失败");
        }
    }

    /**
     * 只允许修改长度与精度 且 新长度与精度必须大于老的
     *
     * @param oldFld
     * @param newFld
     * @return
     */
    private MdMedTbFld getDefaultDimFld(MdMedTbFld oldFld, MdMedTbFld newFld) {
        if (newFld == null) return oldFld;
        if (oldFld == null) return newFld;

        if (newFld.getNumPrec() > oldFld.getNumPrec()) {
            oldFld.setNumPrec(newFld.getNumPrec());
        }
        if (newFld.getNumLth() > oldFld.getNumLth()) {
            oldFld.setNumLth(newFld.getNumLth());
        }

        return oldFld;
    }

    @ApiOperation(value = "维度表的字段")
    @RequestMapping(value = "findTableFld", method = RequestMethod.GET)
    public LayMsg findTableFld(String table) {
        MdMedTb mdMedTb = new MdMedTb();
        mdMedTb.setCd(table);
        List<MdMedTb> byModel = mdMedTbService.findByModel(mdMedTb);
        if (byModel == null || byModel.size() == 0) {
            return LayMsg.fail().addMsg(String.format("表[%s]不存在", table));
        }
        Long idTb = byModel.get(0).getIdTb();
        MdMedTbFld mdMedTbFldModel = new MdMedTbFld();
        mdMedTbFldModel.setIdTb(idTb);
        List<MdMedTbFld> mdMedTbFlds = mdMedTbFldService.findByModel(mdMedTbFldModel);
        Iterator<MdMedTbFld> iterator = mdMedTbFlds.iterator();
        while (iterator.hasNext()) {
            if (DEFAULT_DIM_COLUMN_EUTP.equalsIgnoreCase(iterator.next().getIdPubfld())) {
                iterator.remove();
            }
        }
        return LayMsg.success().addCount(mdMedTbFlds.size()).addData(mdMedTbFlds);
    }


    @ApiOperation(value = "保存")
    @ApiImplicitParam(name = "mdMedPutfd", value = "实体", paramType = "body", required = true, dataType = "MdMedPutfd")
    @RequestMapping(value = "save", method = RequestMethod.POST)
    public LayMsg save(@RequestBody MdMedPubfld mdMedPubfld, HttpServletRequest request) throws BaseException {
        if (mdMedPubfld != null && mdMedPubfld.getFgDim() != 1) {
            mdMedPubfld.setCdDim(null);
            mdMedPubfld.setSdDimtp(null);
            mdMedPubfld.setNaDimtp(null);
            mdMedPubfld.setCdTbDim(null);
        }

        MdMedPubfld oldMdMedPubfld = null;

        if (!StringUtils.isEmpty(mdMedPubfld.getIdPubfld())) {
            oldMdMedPubfld = mdMedPubfldService.getById(mdMedPubfld.getIdPubfld());
            if (oldMdMedPubfld != null) {
                mdMedPubfld.setCd(oldMdMedPubfld.getCd());
                mdMedPubfld.setNa(oldMdMedPubfld.getNa());
                mdMedPubfld.setEuJavatp(oldMdMedPubfld.getEuJavatp());
                mdMedPubfld.setNaJavatp(oldMdMedPubfld.getNaJavatp());
                mdMedPubfld.setNumLth(oldMdMedPubfld.getNumLth());
                mdMedPubfld.setNumPrec(oldMdMedPubfld.getNumPrec());
                mdMedPubfld.setValDef(oldMdMedPubfld.getValDef());
            } else {
                return LayMsg.fail().addMsg(String.format("未找到id为：[%s]的记录。", mdMedPubfld.getIdPubfld()));
            }
        }
        boolean defaultTable;
        try {
            defaultTable = this.createDefaultTable(oldMdMedPubfld, mdMedPubfld);

            if (!defaultTable) {
                return LayMsg.fail().addMsg("保存失败");
            }

            if (StringUtils.isEmpty(mdMedPubfld.getIdPubfld())) {
                mdMedPubfldService.insertSelective(mdMedPubfld);
            } else {
                mdMedPubfldService.updateById(mdMedPubfld);
            }
            return LayMsg.success().addMsg("修改成功");
        } catch (Exception e) {
            e.printStackTrace();
            return LayMsg.fail().addMsg("保存失败：" + e.getMessage());
        }
    }

    private boolean createDefaultTable(MdMedPubfld oldMdMedPubfld, MdMedPubfld mdMedPubfld) throws BaseException {
        //建表
        if (oldMdMedPubfld != null && oldMdMedPubfld.getFgDim() == 1 && mdMedPubfld.getFgDim() != 1 && !StringUtils.isEmpty(oldMdMedPubfld.getCdTbDim())) {
            //刪除维度表
            BaseResult baseResult = commonTableDDLService.dropTableByMedOtherDB(oldMdMedPubfld.getCdTbDim(), null, DBUtil.META_DB);
            return BaseResult.isSuccess(baseResult);
        } else if (mdMedPubfld.getFgDim() == 1 && !StringUtils.isEmpty(mdMedPubfld.getCdTbDim())) {

            MdMedTb mdMedTb = mdMedTbService.getByCd(mdMedPubfld.getCdTbDim());
            MdMedTb OldMdMedTb = mdMedTbService.getByCd(oldMdMedPubfld.getCdTbDim());

            if (oldMdMedPubfld != null && oldMdMedPubfld.getFgDim() == 1 && OldMdMedTb != null
                    && !mdMedPubfld.getCdTbDim().equals(oldMdMedPubfld.getCdTbDim()) && !StringUtils.isEmpty(oldMdMedPubfld.getCdTbDim())) {
                //修改表名
                String oldTableName = oldMdMedPubfld.getCdTbDim();
                OldMdMedTb.setCd(mdMedPubfld.getCdTbDim());
                MdMedTbFld mdMedTbFldModel = new MdMedTbFld();
                mdMedTbFldModel.setIdTb(OldMdMedTb.getIdTb());
                List<MdMedTbFld> mdMedTbFlds = mdMedTbFldService.findByModel(mdMedTbFldModel);
                return commonTableDDLService.alterTableByMedOtherDB(new AlterTableParamVO(OldMdMedTb, mdMedTbFlds, oldTableName), DBUtil.META_DB);
            } else if (mdMedTb == null) {
                //新建表
                mdMedTb = new MdMedTb();
                mdMedTb.setCd(mdMedPubfld.getCdTbDim());
                mdMedTb.setNa(mdMedPubfld.getNa());
                mdMedTb.setFgAct(true);
                mdMedTb.setSdTbca(MedConstant.SD_TBCA_DIM);
                List<MdMedTbFld> mdMedTbFlds = this.generateDefaultFld(mdMedPubfld);
                return commonTableDDLService.alterTableByMedOtherDB(new AlterTableParamVO(mdMedTb, mdMedTbFlds, null), DBUtil.META_DB);
            }
        }
        return true;
    }

    private List<MdMedTbFld> generateDefaultFld(MdMedPubfld mdMedPubfld) {
        List<MdMedTbFld> mdMedTbFlds = new ArrayList();

        MdMedTbFld one = new MdMedTbFld();
        one.setIdPubfld(DEFAULT_DIM_COLUMN_CD);
        one.setNaPubfld(DEFAULT_DIM_COLUMN_CD);
        one.setSdConstp(MedConstant.SD_CONSTP_PK);
        one.setNumLth(mdMedPubfld.getNumLth());
        one.setNumPrec(mdMedPubfld.getNumPrec());
        one.setEuJavatp(mdMedPubfld.getEuJavatp());
        one.setNaJavatp(mdMedPubfld.getNaJavatp());
        mdMedTbFlds.add(one);
        one = new MdMedTbFld();
        one.setIdPubfld(DEFAULT_DIM_COLUMN_NA);
        one.setNaPubfld(DEFAULT_DIM_COLUMN_NA);
        one.setNumLth(100);
        one.setNumPrec(0);
        one.setEuJavatp(12);
        one.setNaJavatp("VARCHAR");
        mdMedTbFlds.add(one);
        one = new MdMedTbFld();
        one.setIdPubfld(DEFAULT_DIM_COLUMN_DES);
        one.setNaPubfld(DEFAULT_DIM_COLUMN_DES);
        one.setNumLth(200);
        one.setNumPrec(0);
        one.setEuJavatp(12);
        one.setNaJavatp("VARCHAR");
        mdMedTbFlds.add(one);
        one = new MdMedTbFld();
        one.setIdPubfld(DEFAULT_DIM_COLUMN_EUTP);
        one.setNaPubfld(DEFAULT_DIM_COLUMN_EUTP);
        one.setNumLth(0);
        one.setNumPrec(0);
        one.setEuJavatp(4);
        one.setNaJavatp("INTEGER");
        mdMedTbFlds.add(one);

        return mdMedTbFlds;
    }

    @ApiOperation(value = "详情")
    @ApiImplicitParam(name = "idPubfld", value = "主键", paramType = "query", required = true, dataType = "String")
    @RequestMapping(value = "getById", method = RequestMethod.GET)
    public BaseResult getById(String idPubfld, HttpServletRequest request) throws BaseException {
        if (StringUtils.isEmpty(idPubfld)) {
            throw new BaseException("请选择要编辑的项");
        }
        MdMedPubfld mdMedPubfld = mdMedPubfldService.getById(idPubfld);
        return new BaseResult(CommonResultConstant.SUCCESS, mdMedPubfld);
    }

    @ApiOperation(value = "根据主键删除")
    @ApiImplicitParam(name = "idPubfld", value = "主键", paramType = "query", required = true, dataType = "String")
    @RequestMapping(value = "delete", method = RequestMethod.GET)
    public BaseResult delete(String idPubfld, HttpServletRequest request) throws BaseException {
        if (StringUtils.isEmpty(idPubfld)) {
            throw new BaseException("请选择要删除的项");
        }
        int num = mdMedPubfldService.deleteById(idPubfld);
        return new BaseResult(CommonResultConstant.SUCCESS, num);
    }


}
